package com.e2edour.lucene;

import com.chenlb.mmseg4j.analysis.ComplexAnalyzer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.custom.CustomAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.synonym.SynonymFilterFactory;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.util.Version;

import java.io.IOException;

/**
 * <p>
 * Lucene 初始化类
 *
 * @author King
 * @since 2017/1/20
 */
public class LuceneInitializeFactory {

    Directory directory = new RAMDirectory();

    private Version lucene630 = Version.LUCENE_6_3_0;
    private SynonymFilterFactory synonymFilterFactory;
    private Analyzer luceneAnalyzer;
    private QueryParser parser;
    private IndexSearcher indexSearcher;

    public Analyzer getLuceneAnalyzer() {
        return luceneAnalyzer;
    }

    public void setLuceneAnalyzer(Analyzer luceneAnalyzer) {
        this.luceneAnalyzer = luceneAnalyzer;
    }

    public QueryParser getParser() {
        return parser;
    }

    public void setParser(QueryParser parser) {
        this.parser = parser;
    }

    public IndexSearcher getIndexSearcher() {
        return indexSearcher;
    }

    public void setIndexSearcher(IndexSearcher indexSearcher) {
        this.indexSearcher = indexSearcher;
    }

    /**
     * 初始索引
     *
     * @throws IOException
     */
    public void initializeIndex() throws IOException {
        initializeAnalyzer();
        IndexWriterConfig writerConfig = new IndexWriterConfig(luceneAnalyzer);
        writerConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        //指定将索引创建信息打印到控制台
        //writerConfig.setInfoStream(System.out);
        IndexWriter writer = new IndexWriter(directory, writerConfig);
        // 创建Document 文档对象，在lucene中创建的索引可以看成数据库中的一张表，表中也可以有字段,往里面添加内容之后可以根据字段去匹配查询
        // 下面创建的doc对象中添加了三个字段，分别为name,sex,dosomething,
        Document doc = new Document();
        doc.add(new Field("name", "lin zhengle", TextField.TYPE_STORED));
        doc.add(new Field("address", "中国上海", TextField.TYPE_STORED));
        doc.add(new Field("dosometing", "京华时报1月23日报道 昨天，受一股来自中西伯利亚的强冷空气影响，本市出现大风降温天气，白天最高气温只有零下7摄氏度，同时伴有6到7级的偏北风。", TextField.TYPE_STORED));
        writer.addDocument(doc);
        //在调用IndexWriter的close()方法时会自动调用commit()方法，在调用commit()方法时会自动调用flush()方法
        writer.close(); // 这里可以提前关闭，因为dictory 写入内存之后 与IndexWriter 没有任何关系了
    }

    private void initializeAnalyzer() {
        luceneAnalyzer = new ComplexAnalyzer();
        luceneAnalyzer.setVersion(lucene630);
    }

    public void initializeSearch() throws IOException {
        DirectoryReader reader = DirectoryReader.open(directory);
        indexSearcher = new IndexSearcher(reader);
        parser = new MultiFieldQueryParser(new String[]{"dosometing"}, luceneAnalyzer);
    }

    public ScoreDoc[] getScoreDocs(String keyWords) throws ParseException, IOException {
        Query query = parser.parse(keyWords);
        TopDocs results = indexSearcher.search(query, 10);
        ScoreDoc[] score = results.scoreDocs;
        for (int i = 0; i < score.length; i++) {
            System.out.println("问题得分：" + score[i].score);
            Document doc = indexSearcher.doc(score[i].doc);
            System.out.println("问题内容：" + doc.get("dosometing"));
        }
        return score;
    }

    public static void main(String[] args) throws IOException, ParseException {
        LuceneInitializeFactory factory = new LuceneInitializeFactory();
        factory.initializeIndex();
        factory.initializeSearch();
        ScoreDoc[] docs = factory.getScoreDocs("强冷空气影响");
        Document doc;
        for (ScoreDoc scoreDoc : docs) {
            doc = factory.getIndexSearcher().doc(scoreDoc.doc);
            if (doc != null) {
                System.out.println(doc.get("dosometing"));
            }
        }
    }
}
